import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import java.awt.Color;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class MainFrame extends JFrame {

	private JPanel contentPane;
	private JTextField textChars;
	private JTextField textWeight;
	private JTextField textString;
	private JLabel lblResult;
	private HuffmanEncode huffmanEncode;
	private JTextArea textCode;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					MainFrame frame = new MainFrame();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public MainFrame() {
		setTitle("Huffman");
		setResizable(false);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 613, 491);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);

		JLabel lblNewLabel = new JLabel("Chars:");
		lblNewLabel.setHorizontalAlignment(SwingConstants.RIGHT);
		lblNewLabel.setBounds(14, 13, 57, 18);
		contentPane.add(lblNewLabel);

		textChars = new JTextField();
		textChars.setText(
				",. ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
		textChars.setBounds(81, 10, 512, 24);
		contentPane.add(textChars);
		textChars.setColumns(10);

		JLabel lblNewLabel_1 = new JLabel("Weight:");
		lblNewLabel_1.setHorizontalAlignment(SwingConstants.RIGHT);
		lblNewLabel_1.setBounds(14, 44, 57, 18);
		contentPane.add(lblNewLabel_1);

		textWeight = new JTextField();
		textWeight.setText(
				"36,87,12,1,17,14,64,52,13,36,27,41,67,85,1,86,74,52,24,54,27,71,18,25,30,30,24,5,11,8,4,68,88,87,54,0,46,50,46,63,52,63,2,43,99,47,83,8,11,97,71,40,22,99,77");
		textWeight.setBounds(81, 47, 393, 24);
		contentPane.add(textWeight);
		textWeight.setColumns(10);

		JButton btnRandom = new JButton("Random");
		btnRandom.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnRandomCall();
			}
		});
		btnRandom.setBounds(487, 44, 106, 27);
		contentPane.add(btnRandom);

		JButton btnCreate = new JButton("Create");
		btnCreate.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnCreateCall();
			}
		});
		btnCreate.setBounds(487, 84, 106, 27);
		contentPane.add(btnCreate);

		lblResult = new JLabel("Please create an HuffmanTree.");
		lblResult.setHorizontalAlignment(SwingConstants.CENTER);
		lblResult.setBorder(BorderFactory.createLineBorder(Color.black));
		lblResult.setBounds(14, 88, 460, 18);
		contentPane.add(lblResult);

		textString = new JTextField();
		textString.setText("hello world.");
		textString.setBounds(81, 119, 512, 24);
		contentPane.add(textString);
		textString.setColumns(10);

		JLabel lblString = new JLabel("String:");
		lblString.setHorizontalAlignment(SwingConstants.RIGHT);
		lblString.setBounds(14, 122, 57, 18);
		contentPane.add(lblString);

		JLabel lblCode = new JLabel("Code:");
		lblCode.setHorizontalAlignment(SwingConstants.LEFT);
		lblCode.setBounds(14, 191, 57, 18);
		contentPane.add(lblCode);

		JButton btnEncode = new JButton("Encode ↓");
		btnEncode.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnEncodeCall();
			}
		});
		btnEncode.setBounds(183, 156, 113, 27);
		contentPane.add(btnEncode);

		JButton btnDecode = new JButton("↑ Decode");
		btnDecode.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnDecodeCall();
			}
		});
		btnDecode.setBounds(395, 156, 113, 27);
		contentPane.add(btnDecode);

		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setBounds(14, 215, 579, 228);
		contentPane.add(scrollPane);

		textCode = new JTextArea();
		textCode.setLineWrap(true);
		textCode.setWrapStyleWord(true);
		scrollPane.setViewportView(textCode);
	}

	protected void btnDecodeCall() {
		if (huffmanEncode == null) {
			lblResult.setText("Please create an HuffmanTree.");
			lblResult.setBorder(BorderFactory.createLineBorder(Color.red));
			return;
		}
		if (textCode.getText().length() < 1) {
			lblResult.setText("Please input the string you want to encode!");
			lblResult.setBorder(BorderFactory.createLineBorder(Color.red));
			return;
		}
		String code = textCode.getText();
		try {
			String string = huffmanEncode.decode(code);
			textString.setText(string);
			lblResult.setBorder(BorderFactory.createLineBorder(Color.green));
		} catch (Exception e) {
			lblResult.setText("Some code can't decode! Check the HuffmanTree!");
			lblResult.setBorder(BorderFactory.createLineBorder(Color.red));
		}
	}

	protected void btnEncodeCall() {
		if (huffmanEncode == null) {
			lblResult.setText("Please create an HuffmanTree.");
			lblResult.setBorder(BorderFactory.createLineBorder(Color.red));
			return;
		}
		if (textString.getText().length() < 1) {
			lblResult.setText("Please input the string you want to encode!");
			lblResult.setBorder(BorderFactory.createLineBorder(Color.red));
			return;
		}
		String string = textString.getText();
		if (!huffmanEncode.canEncode(string)) {
			lblResult
					.setText("Can't encode some chars. Check the HuffmanTree!");
			lblResult.setBorder(BorderFactory.createLineBorder(Color.red));
			return;
		}
		String code = huffmanEncode.encode(string);
		textCode.setText(code);
		lblResult.setBorder(BorderFactory.createLineBorder(Color.green));
	}

	protected void btnCreateCall() {
		if (textChars.getText().length() < 1) {
			lblResult.setText("Please input some chars!");
			lblResult.setBorder(BorderFactory.createLineBorder(Color.red));
			return;
		}
		if (textWeight.getText().length() < 1) {
			lblResult.setText("Please input some weights!");
			lblResult.setBorder(BorderFactory.createLineBorder(Color.red));
			return;
		}
		String[] strweight = textWeight.getText().split(",");
		if (strweight.length != textChars.getText().length()) {
			lblResult.setText("Lengths of chars and weigth is not match!");
			lblResult.setBorder(BorderFactory.createLineBorder(Color.red));
			return;
		}
		int[] weigths = new int[strweight.length];
		for (int i = 0; i < strweight.length; i++) {
			try {
				weigths[i] = Integer.parseInt(strweight[i]);
			} catch (Exception e) {
				lblResult.setText(e.getMessage());
				lblResult.setBorder(BorderFactory.createLineBorder(Color.red));
				return;
			}
		}
		HuffmanTree huffmanTree = new HuffmanTree(weigths);
		huffmanEncode = new HuffmanEncode(huffmanTree, textChars.getText());
		lblResult
				.setText("Created HuffmanTree, you can encode and decode now!");
		lblResult.setBorder(BorderFactory.createLineBorder(Color.green));
	}

	protected void btnRandomCall() {
		if (textChars.getText().length() < 1) {
			lblResult.setText("Please input some chars!");
			return;
		}
		int length = textChars.getText().length();
		String weight = "" + (int) (1 + Math.random() * length);
		for (int i = 1; i < length; i++) {
			int w = 1 + (int) (Math.random() * length);
			weight += "," + w;
		}
		textWeight.setText(weight);
	}
}
